package com.yeyks.common.utils;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 多线程执行MQ信息
 * @author dagny
 * @date 2019/12/30 0030 11:01
 */
@Slf4j
public class BlockThreadPoolExecutor extends ThreadPoolExecutor {

    private ReentrantLock lock = new ReentrantLock();
    private Condition condition = this.lock.newCondition();

    public BlockThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super( corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue );
    }

    @Override
    public void execute(Runnable command) {
        //进行同步锁定
        this.lock.lock();
        super.execute(command);
        try {
            //如果线程池的数量已经达到最大线程池的数量,则进行挂起操作
            if(getPoolSize() == getMaximumPoolSize()){
                this.condition.await();
            }
        }catch (Exception e){
            log.warn( "线程已满！正在挂起" );
        }finally {
            this.lock.unlock();
        }
    }

    //执行后唤醒下一个
    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        try {
            lock.lock();
            //唤醒线程
            this.condition.signal();
        }finally {
            this.lock.unlock();
        }
    }
}
